package com.sfac.day03.modules.account.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sfac.day03.modules.account.dao.UserDao;
import com.sfac.day03.modules.account.dao.UserRoleDao;
import com.sfac.day03.modules.account.entity.User;
import com.sfac.day03.modules.account.entity.UserRole;
import com.sfac.day03.modules.account.service.UserService;
import com.sfac.day03.modules.common.entity.ResultEntity;
import com.sfac.day03.modules.common.entity.SearchBean;
import com.sfac.day03.util.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserRoleDao userRoleDao;
    @Override
    public User getUserByUserNameAndPassword(String userName, String password) {
        return userDao.getUserByUserNameAndPassword(userName, MD5Util.getMD5(userName,password));
    }

    @Override
    public ResultEntity<User> login(User user) {
        User temp = userDao.getUserByUserNameAndPassword(user.getUserName(),
                MD5Util.getMD5(user.getUserName(), user.getPassword()));
        if (temp==null){
            return new ResultEntity<User>(ResultEntity.ResultStatus.FAILED.code,
                    "Username or password is error",user);
        }
        return new ResultEntity<User>(ResultEntity.ResultStatus.SUCCESS.code,
                "Sucess",user);
    }

    @Override
    public void logout() {


    }

    @Override
    @Transactional
    public ResultEntity<User> insertUser(User user) {
        List<User> users = Optional
                .ofNullable(userDao.getUserByUserNameOrEmail(user.getEmail(), user.getUserName()))
                .orElse(Collections.emptyList());
        if (users.size() > 0) {
            return new ResultEntity<User>(ResultEntity.ResultStatus.FAILED.code,
                    "User Name or email is repeat.");
        }

        user.setCreateDate(LocalDateTime.now());
        user.setPassword(MD5Util.getMD5(user.getUserName(), user.getPassword()));
        userDao.insertUser(user);
        User userByUserNameAndPassword = userDao.getUserByUserNameAndPassword(user.getUserName(), user.getPassword());
        user.setId(userByUserNameAndPassword.getId());
        if (user.getRoles() != null) {
            User finalUser = user;
            user.getRoles().stream()
                    .forEach(item -> {userRoleDao.insertUserRole(new UserRole(finalUser.getId(), item.getId()));});
        }
        return new ResultEntity<User>(ResultEntity.ResultStatus.SUCCESS.code, "Insert success", user);
    }

    @Override
    @Transactional
    public ResultEntity<User> updateUser(User user) {
        List<User> users = Optional
                .ofNullable(userDao.getUserByUserNameOrEmail(user.getEmail(), user.getUserName()))
                .orElse(Collections.emptyList());
        if (users.stream().filter(item -> item.getId() != user.getId()).count() > 0) {
            return new ResultEntity<User>(ResultEntity.ResultStatus.FAILED.code, "User Name or email is repeat.");
        }

        userDao.updateUser(user);
        if (user.getRoles() != null && !user.getRoles().isEmpty()) {
            userRoleDao.deleteUserRoleByUserId(user.getId());
            user.getRoles().stream()
                    .forEach(item -> {userRoleDao.insertUserRole(new UserRole(user.getId(), item.getId()));});
        }

        return new ResultEntity<User>(ResultEntity.ResultStatus.SUCCESS.code, "Update success", user);
    }

    @Override
    public User getUserById(int id) {
        return userDao.getUserById(id);
    }

    @Override
    @Transactional
    public ResultEntity<Object> deleteUserById(int id) {
        userDao.deleteUserById(id);
        userRoleDao.deleteUserRoleByUserId(id);
        return new ResultEntity<Object>(ResultEntity.ResultStatus.SUCCESS.code, "Delete success");
    }

    @Override
    public PageInfo<User> getUsersBySearchBean(SearchBean searchBean) {
        searchBean.initSearchBean();
        PageHelper.startPage(searchBean.getPageNumber(), searchBean.getPageSize());
        return new PageInfo<User>(Optional
                .ofNullable(userDao.getUsersBySearchVo(searchBean))
                .orElse(Collections.emptyList()));
    }


    @Override
    public User getUserByUserName(String userName) {
        List<User> users = Optional
                .ofNullable(userDao.getUserByUserName(userName))
                .orElse(Collections.emptyList());
        return users.isEmpty() ? null : users.get(0);
    }
}
